library(FuzzyNumbers)
library(ggplot2)
library(gridExtra)
library(reshape2)
library(rworldmap)El objetivo del proyecto es analizar el CPI (Corruption Perception Index) del 2017 con los datos proporcionados por la organización no gubernamental Transparencia Internacional. El CPI se define en una escala de cero (percepción de alta corrupción) a cien (percepción de ausencia de corrupción).
El CPI es un índice compuesto por las siguientes 13 fuentes de datos:
Cada fuente de dados debe seguir una serie de características para que sea válida. Entre ellas se encuentran la cuantificación de percepción de corrupción en el sector público, cuantificar múltiples países con la misma escala, ser una institución acreditada y tener varios años de datos disponibles. Cabe mencionar que los países no tienen porqué tener información sobre todas las fuentes de datos.
Cada una de estas fuente de datos se estandariza en una escala entre el 0 y el 100, donde 0 es el nivel más alto de percepción de corrupción y 100 es el nivel más bajo. Posteriormente, se calcula el CPI para cada país realizando la media de todas las fuentes de datos que tenga disponibles, con un mínimo de 3 fuentes de datos para poder ser calculado.
Por último, se calcula un error estándar para cada país a partir de la desviación estándar de las fuentes de datos estandarizadas, dividido por la raíz cuadrada de número de fuentes. Este error estándar sirve para calcular un 90% de intervalo de confianza, asumiendo una distribución normal.
data = read.csv('Corruption Perceptions Index - Dataset.csv', sep = ';')
data$african_union = as.logical(data$african_union)
data$arab_states = as.logical(data$arab_states)
data$BRICS = as.logical(data$BRICS)
data$EU = as.logical(data$EU)
data$G20 = as.logical(data$G20)
data$OECD = as.logical(data$OECD)
head(data)str(data)## 'data.frame': 180 obs. of 42 variables:
## $ country : Factor w/ 180 levels "Afghanistan",..: 117 44 55 121 156 143 155 29 97 116 ...
## $ ISO3 : Factor w/ 180 levels "AFG","AGO","ALB",..: 124 45 54 122 28 142 153 27 99 121 ...
## $ region : Factor w/ 6 levels "AME","AP","ECA",..: 2 6 6 6 6 2 6 1 6 6 ...
## $ african_union : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ arab_states : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ BRICS : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ EU : logi FALSE TRUE TRUE FALSE FALSE FALSE ...
## $ G20 : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ OECD : logi TRUE TRUE TRUE TRUE TRUE FALSE ...
## $ CPI_score_2017 : int 89 88 85 85 85 84 84 82 82 82 ...
## $ standard_error_2017 : num 2.4 2.75 2.84 1.83 1.71 2.26 2.27 1.49 2.08 2.23 ...
## $ lower_CI_2017 : int 85 83 80 82 82 80 80 80 79 78 ...
## $ upper_CI_2017 : int 93 93 90 88 88 88 88 84 85 86 ...
## $ number_sources_2017 : int 8 8 8 8 7 9 8 8 6 8 ...
## $ CPI_score_2012 : int 90 90 90 85 86 87 88 84 80 84 ...
## $ standard_error_2012 : num 2.2 2 3 1.6 2.6 2.1 1.9 2.2 2.8 2 ...
## $ number_sources_2012 : int 7 7 7 7 6 9 7 7 6 7 ...
## $ CPI_score_2013 : int 91 91 89 86 85 86 89 81 80 83 ...
## $ standard_error_2013 : num 2.3 2.2 1.7 2.3 2.5 2.3 2.3 2.4 2.9 2 ...
## $ number_sources_2013 : int 7 7 7 7 6 9 7 7 6 7 ...
## $ CPI_score_2014 : int 91 92 89 86 86 84 87 81 82 83 ...
## $ standard_error_2014 : num 2.28 2.04 2.05 2.38 2.61 ...
## $ number_sources_2014 : int 7 7 7 7 6 8 7 7 6 7 ...
## $ CPI_score_2015 : int 91 91 90 88 86 85 89 83 85 84 ...
## $ standard_error_2015 : num 2.32 2.16 1.77 2.24 2.55 ...
## $ number_sources_2015 : int 7 7 7 7 6 8 7 7 5 7 ...
## $ CPI_score_2016 : int 90 90 89 85 86 84 88 82 81 83 ...
## $ standard_error_2016 : num 2.56 2.46 1.46 1.85 1.57 2.35 1.33 2.03 1.96 2.32 ...
## $ number_sources_2016 : int 7 7 7 7 6 8 7 7 6 7 ...
## $ world_bank_CPIA : int 0 0 0 0 0 0 0 0 0 0 ...
## $ world_economic_forum_EOS : int 92 80 92 86 85 90 74 80 86 84 ...
## $ global_insight_country_risk_ratings : int 83 83 83 83 83 83 83 83 83 83 ...
## $ bertelsmann_foundation_transformation_index : int 0 0 0 0 0 73 0 0 0 0 ...
## $ african_development_bank_CPIA : int 0 0 0 0 0 0 0 0 0 0 ...
## $ IMD_world_competitiveness_yearbook : int 93 99 92 85 89 90 84 86 84 89 ...
## $ bertelsmann_foundation_sustainable_governance_index: int 97 97 88 79 88 0 88 79 79 70 ...
## $ world_justice_project_rule_of_law_index : int 82 88 86 86 0 85 86 80 0 80 ...
## $ PRS_international_country_risk_guide : int 93 93 93 93 85 79 93 85 85 85 ...
## $ varieties_of_democracy_project : int 77 77 75 77 77 77 77 77 0 77 ...
## $ economist_intelligence_unit_country_ratings : int 90 90 72 90 90 90 90 90 72 90 ...
## $ freedom_house_nations_in_transit_ratings : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERC_asia_risk_guide : int 0 0 0 0 0 92 0 0 0 0 ...
La variable region representa la región a la que pertenece cada país, siendo:
Las variables african_union, arab_states, BRICS, EU, G20 y OECD son booleanas y representan grupos económicos o foros de los que forman parte los países.
Las variables que representan el CPI, el error estándar y el número de fuentes usadas corresponden desde el año 2012 hasta el 2017. Además, para el año 2017 tenemos el intervalo de confianza mínimo (lower_CI_2017) y el intervalo de confianza máximo (upper_CI_2017) que representa el 90% de intervalo de confianza explicado anteriormente.
Por último, tenemos los valores estandarizados de cada una de las 13 fuentes de datos usadas para calcular el CPI de 2017.
La siguiente gráfica muestra una línea temporal desde 2012 hasta 2017 del CPI de cada año de los 20 países con mayor CPI (menor percepción de corrupción) de 2017.
cols = c('country',
'CPI_score_2012',
'CPI_score_2013',
'CPI_score_2014',
'CPI_score_2015',
'CPI_score_2016',
'CPI_score_2017')
data_cpi = data[cols]
colnames(data_cpi) = c('country', '2012', '2013', '2014', '2015', '2016', '2017')
data_cpi_top_20 = head(data_cpi[sort(data_cpi$`2017`, decreasing = TRUE, index.return=TRUE)$ix, ], 20)
data_cpi_top_20_melt = melt(data_cpi_top_20, id.vars='country')
ggplot(data_cpi_top_20_melt, aes(x=variable, y=value, color=country)) +
geom_point() +
geom_line(aes(group=country)) +
xlab("Year") + ylab("CPI") +
scale_color_discrete(name="Countries",
breaks=data_cpi_top_20$country) +
ggtitle("20 countries with higher CPI in 2017") +
theme(plot.title = element_text(hjust = 0.5))A continuación, se muestra una línea temporal desde 2012 hasta 2017 del CPI de cada año de los 20 países con menor CPI (mayor percepción de corrupción) de 2017.
data_cpi_top_20 = head(data_cpi[sort(data_cpi$`2017`, decreasing = FALSE, index.return=TRUE)$ix, ], 20)
data_cpi_top_20_melt = melt(data_cpi_top_20, id.vars='country')
ggplot(data_cpi_top_20_melt, aes(x=variable, y=value, color=country)) +
geom_point() +
geom_line(aes(group=country)) +
xlab("Year") + ylab("CPI") +
scale_color_discrete(name="Countries",
breaks=data_cpi_top_20$country) +
ggtitle("20 countries with lower CPI in 2017") +
theme(plot.title = element_text(hjust = 0.5))Entre las dos gráficas, se puede apreciar como los países con mayor CPI son regulares año tras año y se mantienen alrededor de las mismas posiciones, mientras que los países con menor CPI son irregulares y cambian de posición continuamente, aunque se mantienen con puntuaciones similares.
La siguiente gráfica muestra una comparación entre la media de CPI y el número de fuentes usadas de cada uno de los años para cada región.
CPI_score_cols = c('CPI_score_2012',
'CPI_score_2013',
'CPI_score_2014',
'CPI_score_2015',
'CPI_score_2016',
'CPI_score_2017')
number_sources_cols = c('number_sources_2012',
'number_sources_2013',
'number_sources_2014',
'number_sources_2015',
'number_sources_2016',
'number_sources_2017')
cols = c(CPI_score_cols, number_sources_cols)
# Calculate mean por each region
ame = sapply(data[data$region == 'AME', cols], mean)
we_eu = sapply(data[data$region == 'WE/EU', cols], mean)
ap = sapply(data[data$region == 'AP', cols], mean)
eca = sapply(data[data$region == 'ECA', cols], mean)
mena = sapply(data[data$region == 'MENA', cols], mean)
ssa = sapply(data[data$region == 'SSA', cols], mean)
regions = rbind(ame, we_eu, ap, eca, mena, ssa)
rownames(regions) = c('AME', 'WE/EU', 'AP', 'ECA', 'MENA', 'SSA')
# Melt dataframes by region
cpi_score_df = regions[, CPI_score_cols]
colnames(cpi_score_df) = c('2012', '2013', '2014', '2015', '2016', '2017')
cpi_score_df_melt = melt(cpi_score_df, id.vars=rownames)
number_sources_df = regions[, number_sources_cols]
colnames(number_sources_df) = c('2012', '2013', '2014', '2015', '2016', '2017')
number_sources_df_melt = melt(number_sources_df, id.vars=rownames)
# Plot comparative between CPI and number of sources
g1 = ggplot(cpi_score_df_melt, aes(x=Var1, y=value, fill=as.factor(Var2))) +
geom_bar(aes(group=Var2), stat = "identity", position = "dodge") +
xlab("Regions") + ylab("Mean CPI") +
ggtitle("Mean CPI by region and year") +
theme(plot.title = element_text(hjust = 0.5),
legend.title=element_blank())
g2 = ggplot(number_sources_df_melt, aes(x=Var1, y=value, fill=as.factor(Var2))) +
geom_bar(aes(group=Var2), stat = "identity", position = "dodge") +
xlab("Regions") + ylab("Mean number of sources") +
ggtitle("Mean number of sources by region and year") +
theme(plot.title = element_text(hjust = 0.5),
legend.title=element_blank())
grid.arrange(g1, g2, nrow = 1)Se puede apreciar una correlación alta entre el CPI y número de fuentes usadas en el cálculo. De media, Europa es la región que mayor CPI tiene en todos los años y la que mayor número de fuentes tiene disponibles. América y Asia/Pacífico están en segunda posición mostrando media muy semblantes. Un caso a analizar es el del Este de Europa/Centro Asia, ya que tiene una baja media de CPI pero con número de fuentes usadas parecido al de Asia/Pacífico y por debajo que América. Estos países tendrán un bajo error estándar ya que se han usado bastantes fuentes para realizar el cálculo.
La siguiente gráfica muestra lo mismo que la anterior, pero por cada grupo económico o foro en el que forman parte los países.
# Calculate mean por each economic group
african_union = sapply(data[data$african_union == TRUE, cols], mean)
arab_states = sapply(data[data$arab_states == TRUE, cols], mean)
BRICS = sapply(data[data$BRICS == TRUE, cols], mean)
EU = sapply(data[data$EU == TRUE, cols], mean)
G20 = sapply(data[data$G20 == TRUE, cols], mean)
OECD = sapply(data[data$OECD == TRUE, cols], mean)
economic_groups = rbind(african_union, arab_states, BRICS, EU, G20, OECD)
rownames(economic_groups) = c('African Union', 'Arab States', 'BRICS', 'EU', 'G20', 'OECD')
# Melt dataframes by economic group
cpi_score_df = economic_groups[, CPI_score_cols]
colnames(cpi_score_df) = c('2012', '2013', '2014', '2015', '2016', '2017')
cpi_score_df_melt = melt(cpi_score_df, id.vars=rownames)
number_sources_df = economic_groups[, number_sources_cols]
colnames(number_sources_df) = c('2012', '2013', '2014', '2015', '2016', '2017')
number_sources_df_melt = melt(number_sources_df, id.vars=rownames)
# Plot comparative between CPI and number of sources
g1 = ggplot(cpi_score_df_melt, aes(x=Var1, y=value, fill=as.factor(Var2))) +
geom_bar(aes(group=Var2), stat = "identity", position = "dodge") +
xlab("Economic groups") + ylab("Mean CPI") +
ggtitle("Mean CPI by economic group and year") +
theme(plot.title = element_text(hjust = 0.5),
legend.title=element_blank())
g2 = ggplot(number_sources_df_melt, aes(x=Var1, y=value, fill=as.factor(Var2))) +
geom_bar(aes(group=Var2), stat = "identity", position = "dodge") +
xlab("Economic groups") + ylab("Mean number of sources") +
ggtitle("Mean number of sources by economic group and year") +
theme(plot.title = element_text(hjust = 0.5),
legend.title=element_blank())
grid.arrange(g1, g2, nrow = 1)En este caso se aprecia aún más que a mayor número de fuentes usadas, mayor CPI, sobre todo en EU, G20 y OECD, los cuales forman parte los países con menor percepción de corrupción y más transparencia. No obstante, BRICS, formada por Brasil, Rusia, India, China y Sudáfrica, es posible que tenga un mayor número de fuentes disponibles por ser una asociación económica-comercial de las economías nacionales emergentes más importantes del mundo y tengan una mayor transparencia, a pesar de ser países con alta percepción de corrupción.
La siguiente gráfica muestra la correlación que hay entre el error estándar y el número de fuentes disponibles en 2017.
ggplot(data, aes(x = standard_error_2017, y = number_sources_2017)) +
geom_point() +
geom_smooth(method = "loess") +
xlab("Standard Error 2017") + ylab("Number of sources 2017") +
ggtitle("Correlation between standard error and number of sources of 2017
with loess smoothed fit curve") +
theme(plot.title = element_text(hjust = 0.5),
legend.title=element_blank())Se puede observar como, en general, los países con mayor número de fuentes son los que tienen un error estándar menor, y viceversa.
Se ha visto que hay una relación entre el CPI, el número de fuentes usadas y el error estándar producido en el cálculo del CPI. Por este motivo, una opción es fuzzificar el CPI de 2017 mediante estas dos últimas variables. No obstante, las variables lower_CI_2017 y upper_CI_2017 indican un intervalo de confianza del 90% calculado a partir del error estándar, por lo que sería más conveniente usar estas variable. Por otro lado, el hecho de que se haya calculado el CPI para un país con pocas fuentes de datos, debería penalizar más que a otro país con el mismo CPI y mayor fuentes de datos. Esto se debe a que, cuantas menos fuentes, más impreciso será el CPI y mayor error se podrá cometer.
Por estos motivos, las variables lower_CI_2017 y upper_CI_2017 se han usado para especificar el core del número borroso ya que, con un 90% de confianza, el CPI de un país estará dentro de ese intervalo. De esta forma, se podrá saber, además, si el error estándar de un país es alto o bajo. El soporte es dos veces la anchura del core. No obstante, para penalizar o beneficiar a un país según el número de fuentes disponibles, se ha aplicado a cada lado del número borroso la proporción del número de fuentes disponibles sobre el total de número de fuentes. Es decir, si un país tiene un número elevado de fuentes disponibles su lado derecho será más largo que el izquierdo, lo que dará más posibilidades de tener valores de CPI mayores que el core que menores. En cambio, si un país tiene un número de fuentes disponibles pequeño, su lado izquierdo será más largo que el derecho, pudiendo obtener un mayor número de valores por debajo del core que por encima. El cálculo para fuzzificar el CPI de cada país se realiza de la siguiente manera, siendo aux1 el valor izquierdo del soporte, aux2 el valor izquierdo del core, aux3 el valor derecho del core y aux4 el valor derecho del soporte:
aux1 = data$lower_CI_2017 -
(2 * (data$upper_CI_2017 - data$lower_CI_2017) * (1 - (data$number_sources_2017 / 13)))
aux2 = data$lower_CI_2017
aux3 = data$upper_CI_2017
aux4 = data$upper_CI_2017 +
(2 * (data$upper_CI_2017 - data$lower_CI_2017) * (data$number_sources_2017 / 13))A continuación, se muestra un ejemplo con la República Checa, la cual tiene 10 fuentes disponibles sobre 13, y las Bahamas, que tiene únicamente 3 fuentes disponibles:
fuzzy_bahamas = PiecewiseLinearFuzzyNumber(aux1[28], aux2[28], aux3[28], aux4[28])
fuzzy_czech_republic = PiecewiseLinearFuzzyNumber(aux1[43], aux2[43], aux3[43], aux4[43])
par(mfrow = c(1, 2))
plot(fuzzy_bahamas, xlim = c(20, 90), main='Bahamas - 3 sources')
plot(fuzzy_czech_republic, xlim = c(45, 75), main='Czech Republic - 10 sources')La fuzzificación del CPI de todos los países puede verse en la siguiente gráfica. La variable fuzzy_CPI guardará los números borrosos de todos los países para posteriores usos.
colors = rainbow(dim(data)[1])
fuzzy_CPI = c()
for(i in 1:nrow(data)) {
fuzzy = PiecewiseLinearFuzzyNumber(aux1[i], aux2[i], aux3[i], aux4[i])
fuzzy_CPI = c(fuzzy_CPI, fuzzy)
add = TRUE
if (i == 1) {
add = FALSE
}
plot(fuzzy, add = add, col = colors[i], xlim = c(-35, 110))
}Se puede observar que hay países que tienen parte del core y del soporte por debajo de 0 y por encima de 100. A pesar de que estos valores no serían válidos para el estudio crisp, en la fuzzificación sí que se tendrán en cuenta por la penalización o el beneficio que causa tener un lado del número borroso más largo que el otro. Si, posteriormente, se saca un número crisp de un número borroso y este está por debajo de 0 o por encima de 100, se dejará como 0 o 100, respectivamente.
Hay un país que destaca por llegar a un valor muy por debajo de 0. Esto puede ser debido a un error estándar muy alto y pocas fuentes disponibles para calcular su CPI. Este país es Comoros y tiene un CPI de 27. Efectivamente, su error estándar es 8.87, dejando los valores del intervalo de confianza en \([12, 42]\), y el número de fuentes disponibles que tiene es 4.
Los cuartiles de números borrosos pueden calcularse a partir de funciones de distribución acumulada generadas mediante una serie de valores delta-cuts especificados por parámetro. Los cuartiles \(Q_1\), \(Q_2\) y \(Q_3\) determinan los valores correspondientes al 25%, 50% y 75% de los datos, siendo \(Q_2\) coincidente con la mediana.
La siguiente función fuzzy_quantile puede calcular el cuartil especificado por el parámetro p, mediante unos delta-cuts especificados en el parámetro deltas. El parámetro fuzzy_number_list será una lista de los números borrosos de nuestro conjunto de datos.
fuzzy_quantile = function(fuzzy_number_list, deltas, p) {
# Calculate delta-cuts of all fuzzy numbers
alphacut_list = c()
for(d in 1:length(deltas)) {
alphacut = c()
for(i in 1:length(fuzzy_number_list)) {
alphacut = c(alphacut, alphacut(fuzzy_number_list[[i]], deltas[d]))
}
alphacut_list[[d]] = sort(alphacut)
}
freq_dist_L = matrix(rep(0, len = length(deltas) * length(fuzzy_number_list) * 2),
nrow = length(deltas))
freq_dist_U = matrix(rep(0, len = length(deltas) * length(fuzzy_number_list) * 2),
nrow = length(deltas))
# Iterate over delta-cuts
for (i in 1:(length(fuzzy_number_list) * 2)) {
# Iterate over the fuzzy numbers
for (fuzzy_num in 1:length(fuzzy_number_list)) {
alphacut = alphacut(fuzzy_number_list[[fuzzy_num]], deltas)
# Iterate over deltas
for (d in 1:length(deltas)) {
# Intersec
if(alphacut[d, 'L'] <= alphacut_list[[d]][i]) {
freq_dist_U[d, i] = freq_dist_U[d, i] + 1
}
# Subset
if(alphacut[d, 'U'] <= alphacut_list[[d]][i]) {
freq_dist_L[d, i] = freq_dist_L[d, i] + 1
}
}
}
}
freq_dist_L = freq_dist_L / length(fuzzy_number_list)
freq_dist_U = freq_dist_U / length(fuzzy_number_list)
m = matrix(rep(0, len = 2 * length(deltas)), nrow = length(deltas))
fuzzy_quantile = data.frame(m, row.names = deltas)
colnames(fuzzy_quantile) = c('L', 'U')
# Upper
for(r in 1:nrow(freq_dist_L)) {
for(c in 1:ncol(freq_dist_L)) {
if(freq_dist_L[r, c] >= p) {
fuzzy_quantile[r, 'U'] = alphacut_list[[r]][c]
break
}
}
}
# Lower
for(r in 1:nrow(freq_dist_U)) {
for(c in 1:ncol(freq_dist_U)) {
if(freq_dist_U[r, c] >= p) {
fuzzy_quantile[r, 'L'] = alphacut_list[[r]][c]
break
}
}
}
return(fuzzy_quantile)
}Primero, calculamos la mediana crisp por región. Las regiones son:
CPI_score_cols = c('CPI_score_2017')
ame = median(data[data$region == 'AME', 'CPI_score_2017'])
we_eu = median(data[data$region == 'WE/EU', 'CPI_score_2017'])
ap = median(data[data$region == 'AP', 'CPI_score_2017'])
eca = median(data[data$region == 'ECA', 'CPI_score_2017'])
mena = median(data[data$region == 'MENA', 'CPI_score_2017'])
ssa = median(data[data$region == 'SSA', 'CPI_score_2017'])
crisp_median_regions = rbind(ame, we_eu, ap, eca, mena, ssa)
rownames(crisp_median_regions) = c('AME', 'WE/EU', 'AP', 'ECA', 'MENA', 'SSA')
crisp_median_regions## [,1]
## AME 38.5
## WE/EU 63.0
## AP 38.0
## ECA 35.0
## MENA 37.5
## SSA 31.0
Destaca la región del Oeste de Europa, con una mayor mediana de CPI. El resto de regiones tienen una mediana de CPI muy parecido.
A continuación, calculamos la mediana borrosa por región con unos delta-cuts de 0, 0.25, 0.5, 0.75 y 1, y una \(p = 0.5\).
region_list = c('AME', 'WE/EU', 'AP', 'ECA', 'MENA', 'SSA')
deltas = c(0, 0.25, 0.5, 0.75, 1)
p = 0.5
country_index_list = lapply(region_list, function(x) as.integer(rownames(data[data$region == x, ])))
median_fuzzy_regions = lapply(country_index_list, function(x) fuzzy_quantile(fuzzy_CPI[x], deltas, p))
median_fuzzy_region_list = c()
legend_text = c()
colors = rainbow(length(median_fuzzy_regions))
# Plot median of the fuzzy numbers with the respective crisp number
for (i in 1:length(median_fuzzy_regions)) {
add = TRUE
if (i == 1) {
add = FALSE
}
fuzzy = median_fuzzy_regions[[i]]
fuzzy_median = PiecewiseLinearFuzzyNumber(fuzzy[1, "L"],
fuzzy[length(deltas), "L"],
fuzzy[length(deltas), "U"],
fuzzy[1, "U"],
knot.n = length(deltas),
knot.alpha = sort(deltas),
knot.left = sort(fuzzy[[1]]),
knot.right = sort(fuzzy[[2]]))
median_fuzzy_region_list = c(median_fuzzy_region_list, fuzzy_median)
plot(fuzzy_median, add = add, col = colors[i], xlim = c(10, 90))
points(crisp_median_regions[i, ], 1, col = colors[i], pch = 8)
legend_text = c(legend_text, region_list[i])
}
legend('topright', legend=legend_text, lty=1, col=colors)Los puntos que aparecen en el core de las medianas borrosas representan los valores de las medianas crisp calculadas anteriormente. Se puede observar como los países del Oeste de Europa son los que mayor CPI tienen (menor percepción de corrupción) y, además, los laterales de su número borroso demuestran que la mayoría tienen un número alto de fuentes disponibles. Del resto de regiones, se aprecia como la que tiene un mayor error estándar es MENA pero con un número de fuentes disponibles de aproximadamente la mitad de las que se podrían tener. La región de África Subsahariana es la que puede llegar a tener un valor de CPI más bajo (mayor percepción de corrupción), además de tener la mayoría de sus países con pocas fuentes de datos disponibles.
A continuación, calculamos el país que se encuentra a una menor distancia de la mediana de cada región mediante la función min_fuzzy_distance, la cual usa la función distance del paquete FuzzyNumbers:
min_fuzzy_distance = function(fuzzy_number_list, fuzzy_number) {
fuzzy_distance = c()
for(i in 1:length(fuzzy_number_list)) {
fuzzy_distance = c(fuzzy_distance, distance(fuzzy_number_list[[i]], fuzzy_number))
}
min_distance = min(fuzzy_distance)
names(min_distance) = which(fuzzy_distance == min_distance)
return(min_distance)
}
min_country_index_list = c()
for (i in 1:length(median_fuzzy_region_list)) {
country_index = country_index_list[[i]]
fuzzy_median = median_fuzzy_region_list[[i]]
min_distance = min_fuzzy_distance(fuzzy_CPI[country_index], fuzzy_median)
min_country_index_list = c(min_country_index_list,
country_index_list[[i]][as.integer(names(min_distance))])
}
data[min_country_index_list, c('region', 'country')]La siguiente gráfica muestra que los países más cercanos a la mediana de su respectiva región ocupan la misma posición que la gráfica anterior:
legend_text = c()
colors = rainbow(length(median_fuzzy_regions))
for (i in 1:length(min_country_index_list)) {
add = TRUE
if (i == 1) {
add = FALSE
}
fuzzy = fuzzy_CPI[[min_country_index_list[i]]]
crisp_CPI = data[min_country_index_list[i], 'CPI_score_2017']
country = as.character(data[min_country_index_list[i], 'country'])
plot(fuzzy, add = add, col = colors[i], xlim = c(10, 90))
points(crisp_CPI, 1, col = colors[i], pch = 8)
legend_text = c(legend_text, country)
}
legend('topright', legend=legend_text, lty=1, col=colors)La siguiente tabla muestra la comparación entre el CPI crisp de 2017 y el CPI desfuzzificado mediante la función expectedValue:
fuzzy_CPI_score_2017 = sapply(fuzzy_CPI, expectedValue)
data['fuzzy_CPI_score_2017'] = round(fuzzy_CPI_score_2017)
data[c('country', 'CPI_score_2017', 'fuzzy_CPI_score_2017')]A partir de esta desfuzzificación, la cual beneficiará o perjudicará a algunos países por cómo se han fuzzificado anteriormente (según el número de fuentes que tengan disponibles y su error estándar). Por lo tanto, se muestra una comparación entre el número crisp y el número desfuzzificado para comprobar cómo ha afectado la fuzzificación del CPI de 2017 de cada país.
par(mfrow = c(2, 1), mai = c(0.1, 0.2, 0.2, 0.2))
n = joinCountryData2Map(data, joinCode="ISO3", nameJoinColumn="ISO3")
# Crisp CPI map
map_params = mapCountryData(n,
nameColumnToPlot="CPI_score_2017",
mapTitle="Crisp Corruption Perception Index 2017",
missingCountryCol="snow2",
colourPalette=c('darkred', 'red', 'yellow'),
borderCol='white',
addLegend=FALSE,
numCats=10,
catMethod=seq(from = 0, to = 100, by = 5))
# Fuzzy CPI map
map_params = mapCountryData(n,
nameColumnToPlot="fuzzy_CPI_score_2017",
mapTitle="Fuzzy Corruption Perception Index 2017",
missingCountryCol="snow2",
colourPalette=c('darkred', 'red', 'yellow'),
borderCol='white',
addLegend=FALSE,
numCats=10,
catMethod=seq(from = 0, to = 100, by = 5))
# Create legend
do.call(addMapLegend,
c(map_params,
legendLabels="all",
legendWidth=0.5,
legendIntervals="data",
legendMar=5))En esta comparación puede observarse como algunos países de Norte-América y el Oeste de Europa mejoran su CPI cuando se fuzzifica debido a que deben de tener un número alto de fuentes disponibles o un error estándar bajo. No obstante, no se aprecia fácilmente si algún país a empeorado sus resultados ya que se pintan diferentes colocres en intervalos de 5 puntos de CPI, por lo que para apreciar un cambio, debería cambiar de rango o haber una diferencia alta. Esto significa que, al haber desfuzzificado el CPI, no ha habido grandes cambios con respecto al valor crisp. A pesar de esto, la fuzzificación del CPI del modo en el que se ha hecho ha servido para saber fácilmente si un país tiene un error estándar o un número de fuentes disponibles alto o bajo.